在 CTF 的比賽中我們很常會遇到需要用 python 寫腳本來解決題目的情況,今天來介紹一些我們在學習資安可能會用到的相關套件!
由於接下來幾天講的內容比較會跟隱寫術或 Web 相關,所以今天主要只介紹了這方面的套件,其他像是 NumPy,Crypto,pwntools 這些工具可能要等之後"Python那些好用的東東(二)" 再來介紹,也就是準備寫密碼學跟 pwn 的時候
一個用於圖像處理的函式庫,它提供了開啟、操作、建立和保存多種影像檔案格式...等多種功能,有時候在做一些隱寫術時會需要他
pip install Pillow
語法 | 功能 | 範例 | 結果 |
---|---|---|---|
Image.open("路徑") | 打開圖片 | Image.open('tmp.png') | 打開tmp.png |
.mode | 圖片模式 | img .mode | RGBA |
.convert() | 轉換圖片模式 | new_img = img.convert('RGB') | 將圖片轉換為RGB模式 |
.save("路徑") | 保存圖片 | img.save('tmp.png') | 儲存圖片為tmp.png |
.size | 圖片大小 | img.size | (500,600) |
.width / .height | 圖片寬高 | img.width / img.height | 500 / 600 |
.resize() | 調整圖片大小 | new_img = img.resize((500,300)) | 將圖片大小轉成 500x300 |
.getpixel(x,y) | 獲取座標(x, y)的像素 | 看下面的簡單範例 | |
.putpixel( ( x, y), (r, g, b, a)) | 將座標(x, y)的像素顏色為(r, g, b, a) | 看下面的簡單範例 |
將圖片 whitebackgound.png 的白色背景改為透明並存成 tmp.png
import PIL.Image as Image
#打開圖片並轉成RGBA的模式
img = Image.open('whitebackgound.png').convert('RGBA')
W, L = img.size
white = (255, 255, 255,255) # 白色
for h in range(W): #遍歷圖片
for i in range(L):
if img.getpixel((h, i)) == white: #如果那格pixel為白色
img.putpixel((h, i), (255, 255, 255, 0)) # 將白色改為透明
img.save('tmp.png') # 保存圖片
Requests 是 python 用於發送 Http 請求的函式庫,它可以模擬各種 Http 請求,並分析回應,也可以應用在爬蟲的時候
pip install requests
語法 | 功能 |
---|---|
requests.get("url") | 發出 get 請求 |
requests.post("url", data={'key':'value'}) | 發出 post 請求,後面可以放資料 |
.url | 返回完整url |
.status_code | 返回HTTP狀態碼 |
.headers | 返回 headers |
.text | 返回內容 |
.json() | 返回 JSON |
.content | 返回二進位內容 |
.cookies | 返回cookies |
這是一份自訂義Header並發送HTTP GET請求到指定的URL的範例
import requests
# 自訂義 Header
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept-Language': 'en-US,en;q=0.9',
}
# 目標網站的 URL
url = 'https://example.com'
# 發送 HTTP GET 請求,使用自訂義的 Header
response = requests.get(url, headers=headers)
# 檢查 HTTP 響應狀態碼
if response.status_code == 200: #如果有成功回應
# 印出網頁內容
print(response.text)
else:
print(f'Error: {response.status_code}')
Scapy是一個用於網絡封包的創建、發送、捕獲和分析等操作的函式庫
pip install scapy
可能要開管理者權限或是sudo
語法 | 功能 |
---|---|
pkt = IP(dst="目標IP") / TCP() | 創建IP/TCP封包 |
send(pkt) | 發送封包 |
pkt.show() | 查看封包的詳細資訊 |
ans, unans = sr(pkt) | 發送並接收封包,並區分回應的列表和無回應的列表 |
pkt[IP].src | 獲取IP封包的源IP地址 |
pkt[TCP].dport | 獲取TCP封包目標端口 |
pkt.summary() | 簡要顯示封包信息 |
pkt.show2() | 更詳細地顯示封包信息 |
pkt[TCP].flags | 獲取TCP封包的標誌位 |
這是一個傳送簡單封包的範例
from scapy.all import *
# 創建一個Ping封包
ping_packet = IP(dst="目標IP") / ICMP()
# 發送Ping封包
response = sr1(ping_packet, timeout=2)
# 檢查是否有回應
if response:
print("目標主機存活")
else:
print("目標主機無回應")
Socket 可以建立起不同主機的 Server 端以及 Client 端,並且讓彼此互相連接、發送訊息
內建函式庫,不用 pip 下載
語法 | 功能 |
---|---|
socket() | 開啟 Socket |
socketpair() | 開啟並連接一對 Socket |
bind() | 定名 Socket |
listen() | 連結 Socket |
accept() | 接受連線 |
send() / write() | 傳送資料 |
sendto() | 傳送 Datagram |
sendmsg() | 傳送交談式訊息 |
recv() / read() | 接收資料 |
recvfrom() | 接收 Datagram |
recvmsg() | 接收交談式訊息 |
close() | 關閉 Socket |
getsockname() | 取得自己 Socket 名稱 |
getpeername() | 取得對方 Socket 名稱 |
setsockopt() | 設定 Socket 參數 |
getsockopt() | 取得 Socket 參數值 |
下面是一個簡單的Server端跟client端的模擬
import socket
import time #time 是為了讀取當前時間
# 設定Server的IP地址和端口
bind_ip = "127.0.0.1"
bind_port = 9999
# 創建Socket,用IPv4 的 TCP/IP 連線
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 綁定Server地址和端口
server.bind((bind_ip, bind_port))
# 開始監聽
server.listen(5)
print("[*] Listening on %s:%d " % (bind_ip, bind_port))
# 設定Server關閉時間(秒)
shutdown_time = 60 # 60秒後關閉Server
# 記錄Server啟動時間
start_time = time.time()
while True:
# 獲取當前時間
current_time = time.time()
# 如果達到關閉時間,則關閉Server,避免程式一直執行
if current_time - start_time >= shutdown_time:
print("[!] Server shutting down.")
server.close()
break
# 等待client端連接
client, addr = server.accept()
print('Connected by', addr)
# 向client端發送消息
client.send(b"Hello, Client!")
# 接收client端的回應
data = client.recv(1024)
print("Client sent data:", data)
# 關閉連接
client.close()
import socket
# 設定Server的IP地址和端口
HOST = '127.0.0.1'
PORT = 9999
# 創建Socket,用IPv4 的 TCP/IP 連線
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
# 讀入資料
cmd = input("Please input msg:")
# 向Server送出資料
s.send(cmd.encode('utf-8'))
# 接收Server送出的資料
data = s.recv(1024)
print ("Server send : %s " % (data))
https://www.readfog.com/a/1635090435931213824
https://wizardforcel.gitbooks.io/scapy-docs/content/1.html
https://docs.python.org/zh-tw/3/howto/sockets.html
https://clay-atlas.com/blog/2019/10/15/python-chinese-tutorial-socket-tcp-ip/
https://ithelp.ithome.com.tw/articles/10226578
http://c.biancheng.net/pillow/
https://steam.oxxostudio.tw/category/python/spider/requests.html